#include <ctype.h>
#include <string.h>
#include <ringlib.h>

int ring_is_full(ring * rng)
{
    if (rng->p_start - rng->p_end + 1 == 0
        || rng->p_start - rng->p_end + 1 == rng->size)
        return TRUE;

    return FALSE;
}

int ring_is_empty(ring * rng)
{
    if (rng->p_start == rng->p_end)
        return TRUE;

    return FALSE;
}

size_t ring_free_size(ring * rng)
{
    int s;

    s = rng->p_end - rng->p_start - 1;

    if (s < 0)
        s += rng->size;

    return (size_t)s;
}

ring * ring_empty(ring * rng)
{
    rng->p_end = rng->p_start = rng->p_buf;

    return rng;
}

size_t ring_data_size(ring * rng)
{
    return rng->size - ring_free_size(rng);
}

size_t ring_data_put(ring * rng, char * bfr, size_t n)
{
    size_t l, s;

    if (n > ring_free_size(rng))
        return 0;

    if (rng->p_end > rng->p_start || rng->p_end == rng->p_buf)
        {
        memcpy(rng->p_start, bfr, n);
        }
    else
        {
        l = n;
        s = rng->p_buf + rng->size - rng->p_start;
        if (s >= l)
            {
            memcpy(rng->p_start, bfr, l);
            }
        else
            {
            memcpy(rng->p_start, bfr, s);
            l -= s;
            bfr += s;
            memcpy(rng->p_buf, bfr, l);
            }
        }

    if (rng->p_start + n > rng->p_buf + rng->size)
        rng->p_start += n - rng->size;
    else
        rng->p_start += n;

    return n;
}

size_t ring_data_get(ring * rng, char * bfr, size_t n)
{
    size_t l, s;

    if (n > ring_data_size(rng))
        return 0;

    if (rng->p_end < rng->p_start || rng->p_end == rng->p_buf)
        {
        memcpy(bfr, rng->p_end, n);
        }
    else
        {
        l = n;
        s = rng->p_buf + rng->size - rng->p_end;
        if (s >= l)
            {
            memcpy(bfr, rng->p_end, l);
            }
        else
            {
            memcpy(bfr, rng->p_end, s);
            l -= s;
            bfr += s;
            memcpy(bfr, rng->p_buf, l);
            }
        }

    if (rng->p_end + n > rng->p_buf + rng->size)
        rng->p_end += n - rng->size;
    else
        rng->p_end += n;

    return n;
}

